#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
混淆器策略统一接口
"""

from abc import ABC, abstractmethod
from dataclasses import dataclass, field
from typing import Dict, List, Optional, Any, TYPE_CHECKING
from enum import Enum

if TYPE_CHECKING:
    from core.builtin_config_module.builtin_config import BuiltInConfig


class ObfuscationLevel(Enum):
    """混淆级别"""
    BASIC = "basic"  # 基础混淆
    STANDARD = "standard"  # 标准混淆
    ADVANCED = "advanced"  # 高级混淆
    MAXIMUM = "maximum"  # 最大混淆


@dataclass
class ObfuscationContext:
    """混淆上下文"""
    project_path: str
    platform: str
    languages: List[str]
    symbol_map: Dict[str, str] = field(default_factory=dict)
    reserved_symbols: List[str] = field(default_factory=list)
    obfuscation_level: ObfuscationLevel = ObfuscationLevel.STANDARD
    options: Dict[str, Any] = field(default_factory=dict)
    metadata: Dict = field(default_factory=dict)
    config: Optional['BuiltInConfig'] = None

    def is_symbol_reserved(self, symbol: str, language: str = "", context: str = "") -> bool:
        """检查符号是否保留"""
        # 优先使用配置中的高级判定逻辑
        if self.config:
            is_safe, _ = self.config.is_symbol_safe_to_obfuscate(
                symbol,
                language=language,
                context=context or self.platform
            )
            if not is_safe:
                return True
        return symbol in self.reserved_symbols

    def get_obfuscated_name(self, original: str) -> Optional[str]:
        """获取混淆后的名称"""
        return self.symbol_map.get(original)

    def add_mapping(self, original: str, obfuscated: str):
        """添加符号映射"""
        if not self.is_symbol_reserved(original):
            self.symbol_map[original] = obfuscated


@dataclass
class ObfuscationResult:
    """混淆结果"""
    success: bool = False
    files_processed: int = 0
    symbols_obfuscated: int = 0
    symbol_map: Dict[str, str] = field(default_factory=dict)
    errors: List[str] = field(default_factory=list)
    warnings: List[str] = field(default_factory=list)
    processing_time: float = 0.0
    metadata: Dict = field(default_factory=dict)

    def merge(self, other: 'ObfuscationResult'):
        """合并另一个结果"""
        self.files_processed += other.files_processed
        self.symbols_obfuscated += other.symbols_obfuscated
        self.symbol_map.update(other.symbol_map)
        self.errors.extend(other.errors)
        self.warnings.extend(other.warnings)
        self.processing_time += other.processing_time
        self.metadata.update(other.metadata)
        # success只有当两者都成功时才为True
        self.success = self.success and other.success


class IObfuscationStrategy(ABC):
    """混淆策略统一接口"""

    @abstractmethod
    def execute(self, context: ObfuscationContext) -> ObfuscationResult:
        """
        执行混淆策略

        Args:
            context: 混淆上下文

        Returns:
            ObfuscationResult: 混淆结果
        """
        pass

    @abstractmethod
    def generate_symbol_mapping(self, symbols: List[str], context: ObfuscationContext) -> Dict[str, str]:
        """
        生成符号映射

        Args:
            symbols: 符号列表
            context: 混淆上下文

        Returns:
            Dict[str, str]: 原始符号到混淆符号的映射
        """
        pass

    @abstractmethod
    def validate_mapping(self, mapping: Dict[str, str], context: ObfuscationContext) -> bool:
        """
        验证符号映射的有效性

        Args:
            mapping: 符号映射
            context: 混淆上下文

        Returns:
            bool: 是否有效
        """
        pass

    @abstractmethod
    def get_strategy_name(self) -> str:
        """
        获取策略名称

        Returns:
            str: 策略名称
        """
        pass

    @abstractmethod
    def get_supported_languages(self) -> List[str]:
        """
        获取支持的语言列表

        Returns:
            List[str]: 支持的语言列表
        """
        pass

    @abstractmethod
    def supports_feature(self, feature: str) -> bool:
        """
        是否支持特定功能

        Args:
            feature: 功能名称（如 'dead_code_injection', 'string_encryption' 等）

        Returns:
            bool: 是否支持
        """
        pass
